home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / _archvrs / unix / unzip51 / mac / mac.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-12  |  10.6 KB  |  461 lines

  1. /*---------------------------------------------------------------------------
  2.  
  3.   mac.c
  4.  
  5.   Macintosh-specific routines for use with Info-ZIP's UnZip 5.1 and later.
  6.  
  7.   This source file incorporates the contents of what was formerly macfile.c,
  8.   which supported commands (such as mkdir()) not available directly on the
  9.   Mac, and which also determined whether HFS (Hierarchical File System) or
  10.   MFS (Macintosh File System) was in use.
  11.  
  12.   ---------------------------------------------------------------------------*/
  13.  
  14.  
  15.  
  16. #ifdef MACOS
  17. #include "unzip.h"
  18.  
  19. #ifndef FSFCBLen
  20. #  define FSFCBLen  (*(short *)0x3F6)
  21. #endif
  22.  
  23. #define read_only   file_attr   /* for readability only */
  24.  
  25. static short wAppVRefNum;
  26. static long lAppDirID;
  27. int hfsflag;            /* set if disk has hierarchical file system */
  28.  
  29.  
  30.  
  31.  
  32.  
  33. /**********************/
  34. /* Function mapattr() */
  35. /**********************/
  36.  
  37. int mapattr()
  38. {
  39.     /* only care about read-only bit, so just look at MS-DOS side of attrs */
  40.     pInfo->read_only = (unsigned)(crec.external_file_attributes & 1);
  41.     return 0;
  42.  
  43. } /* end function mapattr() */
  44.  
  45.  
  46.  
  47.  
  48.  
  49. /**************************************/
  50. /* Function set_file_time_and_close() */
  51. /**************************************/
  52.  
  53. void set_file_time_and_close()
  54. {
  55.     long m_time;
  56.     DateTimeRec dtr;
  57.     ParamBlockRec pbr;
  58.     HParamBlockRec hpbr;
  59.     OSErr err;
  60.  
  61.  
  62.     if (outfd == 1)   /* don't attempt to close or set time on stdout */
  63.         return;
  64.  
  65.     close(outfd);
  66.  
  67.     /*
  68.      * Macintosh bases all file modification times on the number of seconds
  69.      * elapsed since Jan 1, 1904, 00:00:00.  Therefore, to maintain
  70.      * compatibility with MS-DOS archives, which date from Jan 1, 1980,
  71.      * with NO relation to GMT, the following conversions must be made:
  72.      *      the Year (yr) must be incremented by 1980;
  73.      *      and converted to seconds using the Mac routine Date2Secs(),
  74.      *      almost similar in complexity to the Unix version :-)
  75.      *                                     J. Lee
  76.      */
  77.  
  78.     dtr.year = (((lrec.last_mod_file_date >> 9) & 0x7f) + 1980);
  79.     dtr.month = ((lrec.last_mod_file_date >> 5) & 0x0f);
  80.     dtr.day = (lrec.last_mod_file_date & 0x1f);
  81.  
  82.     dtr.hour = ((lrec.last_mod_file_time >> 11) & 0x1f);
  83.     dtr.minute = ((lrec.last_mod_file_time >> 5) & 0x3f);
  84.     dtr.second = ((lrec.last_mod_file_time & 0x1f) * 2);
  85.  
  86.     Date2Secs(&dtr, (unsigned long *)&m_time);
  87.     CtoPstr(filename);
  88.     if (hfsflag) {
  89.         hpbr.fileParam.ioNamePtr = (StringPtr)filename;
  90.         hpbr.fileParam.ioVRefNum = gnVRefNum;
  91.         hpbr.fileParam.ioDirID = glDirID;
  92.         hpbr.fileParam.ioFDirIndex = 0;
  93.         err = PBHGetFInfo(&hpbr, 0L);
  94.         hpbr.fileParam.ioFlMdDat = m_time;
  95.         if ( !fMacZipped )
  96.             hpbr.fileParam.ioFlCrDat = m_time;
  97.         hpbr.fileParam.ioDirID = glDirID;
  98.         if (err == noErr)
  99.             err = PBHSetFInfo(&hpbr, 0L);
  100.         if (err != noErr)
  101.             printf("error:  can't set the time for %s\n", filename);
  102.     } else {
  103.         pbr.fileParam.ioNamePtr = (StringPtr)filename;
  104.         pbr.fileParam.ioVRefNum = pbr.fileParam.ioFVersNum =
  105.           pbr.fileParam.ioFDirIndex = 0;
  106.         err = PBGetFInfo(&pbr, 0L);
  107.         pbr.fileParam.ioFlMdDat = pbr.fileParam.ioFlCrDat = m_time;
  108.         if (err == noErr)
  109.             err = PBSetFInfo(&pbr, 0L);
  110.         if (err != noErr)
  111.             printf("error:  can't set the time for %s\n", filename);
  112.     }
  113.  
  114.     /* set read-only perms if needed */
  115.     if ((err == noErr) && pInfo->read_only) {
  116.         if (hfsflag) {
  117.             hpbr.fileParam.ioNamePtr = (StringPtr)filename;
  118.             hpbr.fileParam.ioVRefNum = gnVRefNum;
  119.             hpbr.fileParam.ioDirID = glDirID;
  120.             err = PBHSetFLock(&hpbr, 0);
  121.         } else
  122.             err = SetFLock((ConstStr255Param)filename, 0);
  123.     }
  124.     PtoCstr(filename);
  125.  
  126. } /* end function set_file_time_and_close() (Mac) */
  127.  
  128.  
  129.  
  130.  
  131.  
  132. /************************/
  133. /* Function IsHFSDisk() */
  134. /************************/
  135.  
  136. static int IsHFSDisk(short wRefNum)
  137. {
  138.     /* get info about the specified volume */
  139.     if (hfsflag == true) {
  140.         HParamBlockRec    hpbr;
  141.         Str255 temp;
  142.         short wErr;
  143.         
  144.         hpbr.volumeParam.ioCompletion = 0;
  145.         hpbr.volumeParam.ioNamePtr = temp;
  146.         hpbr.volumeParam.ioVRefNum = wRefNum;
  147.         hpbr.volumeParam.ioVolIndex = 0;
  148.         wErr = PBHGetVInfo(&hpbr, 0);
  149.  
  150.         if (wErr == noErr && hpbr.volumeParam.ioVFSID == 0
  151.             && hpbr.volumeParam.ioVSigWord == 0x4244) {
  152.                 return true;
  153.         }
  154.     }
  155.  
  156.     return false;
  157. } /* IsHFSDisk */
  158.  
  159.  
  160.  
  161.  
  162.  
  163. /************************/
  164. /* Function macfstest() */
  165. /************************/
  166.  
  167. void macfstest(int vrefnum)
  168. {
  169.     Str255 st;
  170.  
  171.     /* is this machine running HFS file system? */
  172.     if (FSFCBLen <= 0) {
  173.         hfsflag = false;
  174.     }
  175.     else
  176.     {
  177.         hfsflag = true;
  178.     }
  179.  
  180.     /* get the file's volume reference number and directory ID */
  181.     if (hfsflag == true) {
  182.         WDPBRec    wdpb;
  183.         OSErr err = noErr;
  184.  
  185.         if (vrefnum != 0) {
  186.             wdpb.ioCompletion = false;
  187.             wdpb.ioNamePtr = st;
  188.             wdpb.ioWDIndex = 0;
  189.             wdpb.ioVRefNum = vrefnum;
  190.             err = PBHGetVol(&wdpb, false);
  191.         
  192.             if (err == noErr) {
  193.                 wAppVRefNum = wdpb.ioWDVRefNum;
  194.                 lAppDirID = wdpb.ioWDDirID;
  195.             }
  196.         }
  197.  
  198.         /* is the disk we're using formatted for HFS? */
  199.         hfsflag = IsHFSDisk(wAppVRefNum);
  200.     }
  201.     
  202.     return;
  203. } /* mactest */
  204.  
  205.  
  206.  
  207.  
  208.  
  209. /***********************/
  210. /* Function macmkdir() */
  211. /***********************/
  212.  
  213. int macmkdir(char *path, short nVRefNum, long lDirID)
  214. {
  215.     OSErr    err = -1;
  216.  
  217.     if (path != 0 && strlen(path)<256 && hfsflag == true) {
  218.         HParamBlockRec    hpbr;
  219.         Str255    st;
  220.  
  221.         CtoPstr(path);
  222.         if ((nVRefNum == 0) && (lDirID == 0))
  223.         {
  224.             hpbr.fileParam.ioNamePtr = st;
  225.             hpbr.fileParam.ioCompletion = NULL;
  226.             err = PBHGetVol((WDPBPtr)&hpbr, false);
  227.             nVRefNum = hpbr.wdParam.ioWDVRefNum;
  228.             lDirID = hpbr.wdParam.ioWDDirID;
  229.         }
  230.         else
  231.         {
  232.             err = noErr;
  233.         }
  234.         if (err == noErr) {
  235.             hpbr.fileParam.ioCompletion = NULL;
  236.             hpbr.fileParam.ioVRefNum = nVRefNum;
  237.             hpbr.fileParam.ioDirID = lDirID;
  238.             hpbr.fileParam.ioNamePtr = (StringPtr)path;
  239.             err = PBDirCreate(&hpbr, false);
  240.         }    
  241.         PtoCstr(path);
  242.     }
  243.  
  244.     return (int)err;
  245. } /* mkdir */
  246.  
  247.  
  248.  
  249.  
  250.  
  251. /****************************/
  252. /* Function ResolveMacVol() */
  253. /****************************/
  254.  
  255. void ResolveMacVol(short nVRefNum, short *pnVRefNum, long *plDirID, StringPtr pst)
  256. {
  257.     if (hfsflag)
  258.     {
  259.         WDPBRec  wdpbr;
  260.         Str255   st;
  261.         OSErr    err;
  262.  
  263.         wdpbr.ioCompletion = (ProcPtr)NULL;
  264.         wdpbr.ioNamePtr = st;
  265.         wdpbr.ioVRefNum = nVRefNum;
  266.         wdpbr.ioWDIndex = 0;
  267.         wdpbr.ioWDProcID = 0;
  268.         wdpbr.ioWDVRefNum = 0;
  269.         err = PBGetWDInfo( &wdpbr, false );
  270.         if ( err == noErr )
  271.         {
  272.             if (pnVRefNum)
  273.                 *pnVRefNum = wdpbr.ioWDVRefNum;
  274.             if (plDirID)
  275.                 *plDirID = wdpbr.ioWDDirID;
  276.             if (pst)
  277.                 BlockMove( st, pst, st[0]+1 );
  278.         }
  279.     }
  280.     else
  281.     {
  282.         if (pnVRefNum)
  283.             *pnVRefNum = nVRefNum;
  284.         if (plDirID)
  285.             *plDirID = 0;
  286.         if (pst)
  287.             *pst = 0;
  288.     }
  289. }
  290.  
  291.  
  292.  
  293.  
  294.  
  295. /**********************/
  296. /* Function macopen() */
  297. /**********************/
  298.  
  299. short macopen(char *sz, short nFlags, short nVRefNum, long lDirID)
  300. {
  301.     OSErr   err;
  302.     Str255  st;
  303.     char    chPerms = (!nFlags) ? fsRdPerm : fsRdWrPerm;
  304.     short   nFRefNum;
  305.  
  306.     CtoPstr( sz );
  307.     BlockMove( sz, st, sz[0]+1 );
  308.     PtoCstr( sz );
  309.     if (hfsflag)
  310.     {
  311.         if (nFlags > 1)
  312.             err = HOpenRF( nVRefNum, lDirID, st, chPerms, &nFRefNum);
  313.         else
  314.             err = HOpen( nVRefNum, lDirID, st, chPerms, &nFRefNum);
  315.     }
  316.     else
  317.     {
  318.         /*
  319.          * Have to use PBxxx style calls since the high level
  320.          * versions don't support specifying permissions
  321.          */
  322.         ParamBlockRec    pbr;
  323.  
  324.         pbr.ioParam.ioNamePtr = st;
  325.         pbr.ioParam.ioVRefNum = gnVRefNum;
  326.         pbr.ioParam.ioVersNum = 0;
  327.         pbr.ioParam.ioPermssn = chPerms;
  328.         pbr.ioParam.ioMisc = 0;
  329.         if (nFlags >1)
  330.             err = PBOpenRF( &pbr, false );
  331.         else
  332.             err = PBOpen( &pbr, false );
  333.         nFRefNum = pbr.ioParam.ioRefNum;
  334.     }
  335.     if ( err )
  336.         return -1;
  337.     else
  338.         return nFRefNum;
  339. }
  340.  
  341.  
  342.  
  343.  
  344.  
  345. /***********************/
  346. /* Function maccreat() */
  347. /***********************/
  348.  
  349. short maccreat(char *sz, short nVRefNum, long lDirID, OSType ostCreator, OSType ostType)
  350. {
  351.     OSErr   err;
  352.     Str255  st;
  353.     FInfo   fi;
  354.  
  355.     CtoPstr( sz );
  356.     BlockMove( sz, st, sz[0]+1 );
  357.     PtoCstr( sz );
  358.     if (hfsflag)
  359.     {
  360.         err = HGetFInfo( nVRefNum, lDirID, st, &fi );
  361.         if (err == fnfErr)
  362.             err = HCreate( nVRefNum, lDirID, st, ostCreator, ostType );
  363.         else if (err == noErr)
  364.         {
  365.             fi.fdCreator = ostCreator;
  366.             fi.fdType = ostType;
  367.             err = HSetFInfo( nVRefNum, lDirID, st, &fi );
  368.         }
  369.     }
  370.     else
  371.     {
  372.         err = GetFInfo( st, nVRefNum, &fi );
  373.         if (err == fnfErr)
  374.             err = Create( st, nVRefNum, ostCreator, ostType );
  375.         else if (err == noErr)
  376.         {
  377.             fi.fdCreator = ostCreator;
  378.             fi.fdType = ostType;
  379.             err = SetFInfo( st, nVRefNum, &fi );
  380.         }
  381.     }
  382.     if (err == noErr)
  383.         return noErr;
  384.     else
  385.         return -1;
  386. }
  387.  
  388.  
  389.  
  390.  
  391.  
  392. /**********************/
  393. /* Function macread() */
  394. /**********************/
  395.  
  396. short macread(short nFRefNum, char *pb, unsigned cb)
  397. {
  398.     long    lcb = cb;
  399.  
  400.     (void)FSRead( nFRefNum, &lcb, pb );
  401.  
  402.     return (short)lcb;
  403. }
  404.  
  405.  
  406.  
  407.  
  408.  
  409. /***********************/
  410. /* Function macwrite() */
  411. /***********************/
  412.  
  413. short macwrite(short nFRefNum, char *pb, unsigned cb)
  414. {
  415.     long    lcb = cb;
  416.  
  417.     (void)FSWrite( nFRefNum, &lcb, pb );
  418.  
  419.     return (short)lcb;
  420. }
  421.  
  422.  
  423.  
  424.  
  425.  
  426. /***********************/
  427. /* Function macclose() */
  428. /***********************/
  429.  
  430. short macclose(short nFRefNum)
  431. {
  432.     return FSClose( nFRefNum );
  433. }
  434.  
  435.  
  436.  
  437.  
  438.  
  439. /***********************/
  440. /* Function maclseek() */
  441. /***********************/
  442.  
  443. long maclseek(short nFRefNum, long lib, short nMode)
  444. {
  445.     ParamBlockRec   pbr;
  446.  
  447.     if (nMode == SEEK_SET)
  448.         nMode = fsFromStart;
  449.     else if (nMode == SEEK_CUR)
  450.         nMode = fsFromMark;
  451.     else if (nMode == SEEK_END)
  452.         nMode = fsFromLEOF;
  453.     pbr.ioParam.ioRefNum = nFRefNum;
  454.     pbr.ioParam.ioPosMode = nMode;
  455.     pbr.ioParam.ioPosOffset = lib;
  456.     (void)PBSetFPos(&pbr, 0);
  457.     return pbr.ioParam.ioPosOffset;
  458. }
  459.  
  460. #endif /* MACOS */
  461.